package com.franklin.java.action.sql.entity.ui;

import com.flychord.jdk.util.matchcase.TupleCase;
import com.flychord.jdk.util.tuple.Tuple2;
import com.franklin.java.configuration.sql.completion.CompletionSettingState;
import com.franklin.plugins.common.collection.PrettyArrayList;
import com.franklin.plugins.common.utils.DataCheckUtils;
import com.franklin.plugins.common.utils.StringHelper;
import com.google.common.collect.Lists;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.ui.treeStructure.SimpleNode;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.flychord.jdk.util.tuple.TupleAble.tuple;
import static com.franklin.java.action.sql.entity.ui.GenerateEntityClassForm.prefixTab;

/**
 * @author Franklin
 * @since 2021/9/13 14:32
 */
public class ConstructorNode extends ResultMapChildNode{

    protected ConstructorNode(SimpleNode aParent) {
        super(aParent);
        setProperties();
    }

    @Override
    public List<String> getChildNodeNames() {
        return Lists.newArrayList(
            "idArg","arg"
        );
    }


    @Override
    public boolean isSingleTag() {
        return false;
    }

    @Override
    public String classMember(String className, Set<String> importSet) {
        StringBuilder constructorBuilder = new StringBuilder();
        List<ResultMapChildNode> constructorChildren = this.getChildrenNodeList();
        if (DataCheckUtils.isNotEmpty(constructorChildren)) {
            boolean useCamel = CompletionSettingState.isUseCamel(project);
            StringBuilder paramBuilder = new StringBuilder();
            String params = constructorChildren.stream()
                .map(childNode -> {
                    String fieldName = childNode.getProperty("name");
                    if (DataCheckUtils.isEmpty(fieldName)) {
                        String column = childNode.getProperty("column");
                        if (useCamel) {
                            fieldName = StringHelper.underlineToCamel(column);
                        } else {
                            fieldName = column;
                        }
                    }
                    String javaType = childNode.getProperty("javaType");
                    return tuple(fieldName, javaType);
                })
                .filter(tuple -> DataCheckUtils.isNotEmpty(tuple._1()))
                .map(
                    TupleCase.match(
                        (fieldName, javaType) -> {
                            paramBuilder
                                .append(prefixTab).append(prefixTab)
                                .append("this.").append(fieldName)
                                .append(" = ").append(fieldName).append(";\n");
                            importSet.add(javaType);
                            return StringHelper.getSimpleName(javaType) + " " + fieldName;
                        }
                    )
                )
                .collect(Collectors.joining(","));

            constructorBuilder
                .append("public ").append(className)
                .append('(').append(params).append("){\n")
                .append(paramBuilder)
                .append(prefixTab).append("}\n");
        }
        return constructorBuilder.toString();
    }

    @Override
    public @NlsSafe String getName() {
        return "<constructor>";
    }

    @Override
    protected void setProperties() {
        this.properties = new PrettyArrayList<>();
    }

    public static class ArgNode extends ResultMapChildNode{

        private String column;
        private String javaType;
        private String name;

        protected ArgNode(SimpleNode aParent, String column, String javaType, String name) {
            super(aParent);
            this.column = column;
            this.javaType = javaType;
            this.name = name;
            setProperties();
        }

        @Override
        protected void setProperties() {
            List<Tuple2<String, String>> tuple2List = new PrettyArrayList<>();
            tuple2List.add(tuple("column",column));
            tuple2List.add(tuple("javaType",javaType));
            tuple2List.add(tuple("name",name));
            this.properties = tuple2List;
        }

        @Override
        public boolean isSingleTag() {
            return true;
        }

        @Override
        public List<String> getChildNodeNames() {
            return Collections.emptyList();
        }

    }

    public static class IdArgNode extends ArgNode {

        protected IdArgNode(SimpleNode aParent, String column, String javaType, String name) {
            super(aParent, column, javaType, name);
            setProperties();
        }
    }
}
